package pipeline

import (
	"context"
	"fmt"
	"io/ioutil"
	"time"

	"mcp-server/internal/docprocessor"
	"mcp-server/internal/metadata"
	"mcp-server/internal/storage"
	"mcp-server/internal/vector"
)

// FileReaderProcessor 文件读取处理器
type FileReaderProcessor struct{}

func NewFileReaderProcessor() *FileReaderProcessor {
	return &FileReaderProcessor{}
}

func (p *FileReaderProcessor) GetName() string {
	return "FileReader"
}

func (p *FileReaderProcessor) GetStage() ProcessingStage {
	return StageReading
}

func (p *FileReaderProcessor) Process(ctx context.Context, task *PipelineTask) error {
	startTime := time.Now()

	// 读取文件内容
	content, err := ioutil.ReadFile(task.FilePath)
	if err != nil {
		return fmt.Errorf("failed to read file: %w", err)
	}

	task.Content = string(content)

	// 更新统计信息
	if task.Result == nil {
		task.Result = &TaskResult{
			Statistics: &ProcessingStatistics{},
		}
	}
	task.Result.Statistics.ReadTime = time.Since(startTime)
	task.Result.Statistics.FileSize = int64(len(content))

	return nil
}

// DocumentParserProcessor 文档解析处理器
type DocumentParserProcessor struct {
	processor *docprocessor.DocumentProcessor
}

func NewDocumentParserProcessor(processor *docprocessor.DocumentProcessor) *DocumentParserProcessor {
	return &DocumentParserProcessor{
		processor: processor,
	}
}

func (p *DocumentParserProcessor) GetName() string {
	return "DocumentParser"
}

func (p *DocumentParserProcessor) GetStage() ProcessingStage {
	return StageParsing
}

func (p *DocumentParserProcessor) Process(ctx context.Context, task *PipelineTask) error {
	startTime := time.Now()

	// 使用文档处理器处理文件
	splitResult, err := p.processor.ProcessFile(task.FilePath)
	if err != nil {
		return fmt.Errorf("failed to parse document: %w", err)
	}

	// 将解析结果存储在任务中
	if splitResult.Document != nil {
		task.Content = splitResult.Document.FileName // 使用文档信息
	}

	// 更新统计信息
	task.Result.Statistics.ParseTime = time.Since(startTime)

	return nil
}

// MetadataExtractorProcessor 元数据提取处理器
type MetadataExtractorProcessor struct {
	manager *metadata.DefaultManager
}

func NewMetadataExtractorProcessor(manager *metadata.DefaultManager) *MetadataExtractorProcessor {
	return &MetadataExtractorProcessor{
		manager: manager,
	}
}

func (p *MetadataExtractorProcessor) GetName() string {
	return "MetadataExtractor"
}

func (p *MetadataExtractorProcessor) GetStage() ProcessingStage {
	return StageMetadata
}

func (p *MetadataExtractorProcessor) Process(ctx context.Context, task *PipelineTask) error {
	if !task.Config.ExtractMetadata {
		return nil // 跳过元数据提取
	}

	startTime := time.Now()

	// 使用元数据管理器处理文件
	metadata, err := p.manager.ProcessFile(task.FilePath)
	if err != nil {
		return fmt.Errorf("failed to extract metadata: %w", err)
	}

	// 存储元数据
	task.Progress.Metadata = metadata

	// 更新统计信息
	task.Result.Statistics.MetadataTime = time.Since(startTime)

	return nil
}

// TextSplitterProcessor 文本分片处理器
type TextSplitterProcessor struct {
	processor *docprocessor.DocumentProcessor
}

func NewTextSplitterProcessor(processor *docprocessor.DocumentProcessor) *TextSplitterProcessor {
	return &TextSplitterProcessor{
		processor: processor,
	}
}

func (p *TextSplitterProcessor) GetName() string {
	return "TextSplitter"
}

func (p *TextSplitterProcessor) GetStage() ProcessingStage {
	return StageSplitting
}

func (p *TextSplitterProcessor) Process(ctx context.Context, task *PipelineTask) error {
	startTime := time.Now()

	// 使用文档处理器进行分片
	splitResult, err := p.processor.ProcessFile(task.FilePath)
	if err != nil {
		return fmt.Errorf("failed to split document: %w", err)
	}

	// 更新任务进度
	task.Progress.TotalChunks = len(splitResult.Chunks)
	task.Progress.ProcessedChunks = 0

	// 将分片结果存储在任务中（通过扩展任务结构或使用上下文）
	// 这里我们需要一个方式来传递chunks到下一个处理器
	// 可以通过扩展PipelineTask结构或使用context来实现

	// 更新统计信息
	task.Result.Statistics.SplitTime = time.Since(startTime)
	task.Result.Statistics.ChunkCount = len(splitResult.Chunks)

	return nil
}

// VectorizerProcessor 向量化处理器
type VectorizerProcessor struct {
	manager *vector.VectorManager
}

func NewVectorizerProcessor(manager *vector.VectorManager) *VectorizerProcessor {
	return &VectorizerProcessor{
		manager: manager,
	}
}

func (p *VectorizerProcessor) GetName() string {
	return "Vectorizer"
}

func (p *VectorizerProcessor) GetStage() ProcessingStage {
	return StageVectorizing
}

func (p *VectorizerProcessor) Process(ctx context.Context, task *PipelineTask) error {
	startTime := time.Now()

	// 检查向量管理器是否已初始化
	if !p.manager.IsInitialized() {
		// 向量管理器未初始化，跳过向量化步骤
		task.Result.Statistics.VectorizeTime = time.Since(startTime)
		task.Result.Statistics.VectorCount = 0
		task.Result.GeneratedVectors = 0
		return nil
	}

	// 使用向量管理器处理文档
	updateResult, err := p.manager.ProcessAndStoreDocument(task.FilePath)
	if err != nil {
		// 如果向量化失败，记录错误但不阻止流水线继续
		task.Result.Statistics.VectorizeTime = time.Since(startTime)
		task.Result.Statistics.VectorCount = 0
		task.Result.GeneratedVectors = 0
		return fmt.Errorf("failed to vectorize document: %w", err)
	}

	// 如果有元数据，增强向量
	if task.Progress.Metadata != nil {
		// 这里可以调用元数据集成功能来增强向量
		// enhancedVectors := metadata.EnhanceVectors(vectors, task.Progress.Metadata)
	}

	// 更新统计信息
	task.Result.Statistics.VectorizeTime = time.Since(startTime)
	task.Result.Statistics.VectorCount = updateResult.VectorizedChunks
	task.Result.GeneratedVectors = updateResult.VectorizedChunks

	return nil
}

// StorageProcessor 存储处理器
type StorageProcessor struct {
	manager *storage.StorageManager
}

func NewStorageProcessor(manager *storage.StorageManager) *StorageProcessor {
	return &StorageProcessor{
		manager: manager,
	}
}

func (p *StorageProcessor) GetName() string {
	return "Storage"
}

func (p *StorageProcessor) GetStage() ProcessingStage {
	return StageStoring
}

func (p *StorageProcessor) Process(ctx context.Context, task *PipelineTask) error {
	startTime := time.Now()

	// 在向量化处理器中已经完成了存储，这里只是记录时间
	// 实际的存储逻辑已经在VectorizerProcessor中完成

	// 更新统计信息
	task.Result.Statistics.StoreTime = time.Since(startTime)

	return nil
}

// RetryableProcessor 可重试处理器包装器
type RetryableProcessor struct {
	processor  ProcessorInterface
	maxRetries int
	retryDelay time.Duration
}

func NewRetryableProcessor(processor ProcessorInterface, maxRetries int, retryDelay time.Duration) *RetryableProcessor {
	return &RetryableProcessor{
		processor:  processor,
		maxRetries: maxRetries,
		retryDelay: retryDelay,
	}
}

func (p *RetryableProcessor) GetName() string {
	return fmt.Sprintf("Retryable(%s)", p.processor.GetName())
}

func (p *RetryableProcessor) GetStage() ProcessingStage {
	return p.processor.GetStage()
}

func (p *RetryableProcessor) Process(ctx context.Context, task *PipelineTask) error {
	var lastErr error

	for attempt := 0; attempt <= p.maxRetries; attempt++ {
		if attempt > 0 {
			// 等待重试延迟
			select {
			case <-time.After(p.retryDelay):
			case <-ctx.Done():
				return ctx.Err()
			}
		}

		err := p.processor.Process(ctx, task)
		if err == nil {
			return nil // 成功
		}

		lastErr = err

		// 检查是否应该重试
		if !shouldRetry(err) {
			break
		}
	}

	return fmt.Errorf("failed after %d attempts: %w", p.maxRetries+1, lastErr)
}

// shouldRetry 判断是否应该重试
func shouldRetry(err error) bool {
	// 这里可以根据错误类型判断是否应该重试
	// 例如网络错误、临时性错误等可以重试
	// 而文件不存在、权限错误等不应该重试
	return true // 简化实现，所有错误都重试
}
